package com.codeavatar.catools.helper;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.InputType;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.StyleSpan;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.appcompat.widget.LinearLayoutCompat;

import java.util.ArrayList;
import java.util.List;

/**
 * +----------------------------------------------------------------------
 * | @Author: codeavatar   @Year：2022
 * +----------------------------------------------------------------------
 * | @Email: codeavatar@aliyun.com
 * +----------------------------------------------------------------------
 **/
public class CaViewHelper {

    private final String TAG = this.getClass().getSimpleName();

    //++++++++++++++++++++++++++++++++++++++
    //++ 外部方法
    //++++++++++++++++++++++++++++++++++++++

    //读取可点击的文本
    public String getClickText(View clickableSpanOnclickWidget) {
        if (null == clickableSpanOnclickWidget) {
            return "";
        }
        TextView tvw = (TextView) clickableSpanOnclickWidget;
        return tvw.getText().subSequence(tvw.getSelectionStart(), tvw.getSelectionEnd()).toString().trim();
    }

    //设置点击的文本
    public void setClickText(TextView tvwView, String strText, String clickText[], ClickableSpan clickSpan[]) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(strText);
        if (clickText.length <= clickSpan.length) {
            for (int i = 0; i < clickText.length; i++) {
                int beginIndex = strText.indexOf(clickText[i]);
                int endIndex = beginIndex + clickText[i].length();
                ssb.setSpan(clickSpan[i], beginIndex, endIndex, 0);
            }
            tvwView.setMovementMethod(LinkMovementMethod.getInstance());
            tvwView.setText(ssb, TextView.BufferType.SPANNABLE);
        }
    }

    /**
     * 设置子视图单击事件
     *
     * @param lltContainer
     * @param listener
     */
    public void setOnChildViewClick(LinearLayoutCompat lltContainer, View.OnClickListener listener) {
        if (null == lltContainer || null == listener) return;

        //第二层
        for (int i = 0; i < lltContainer.getChildCount(); i++) {
            View tmpView = lltContainer.getChildAt(i);
            if (tmpView.getId() != 0) {
                tmpView.setOnClickListener(listener);
            } else {
                if (tmpView instanceof LinearLayout) {
                    LinearLayout tmpLltContainer = (LinearLayout) tmpView;
                    //第三层
                    for (int m = 0; m < tmpLltContainer.getChildCount(); m++) {
                        View tmpChildView = tmpLltContainer.getChildAt(m);
                        if (tmpChildView.getId() != 0) {
                            tmpChildView.setOnClickListener(listener);
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置子视图单击事件
     *
     * @param lltContainer
     * @param listener
     */
    public void setOnChildViewClick(LinearLayout lltContainer, View.OnClickListener listener) {
        if (null == lltContainer || null == listener) return;

        //第二层
        for (int i = 0; i < lltContainer.getChildCount(); i++) {
            View tmpView = lltContainer.getChildAt(i);
            if (tmpView.getId() != 0) {
                tmpView.setOnClickListener(listener);
            } else {
                if (tmpView instanceof LinearLayout) {
                    LinearLayout tmpLltContainer = (LinearLayout) tmpView;
                    //第三层
                    for (int m = 0; m < tmpLltContainer.getChildCount(); m++) {
                        View tmpChildView = tmpLltContainer.getChildAt(m);
                        if (tmpChildView.getId() != 0) {
                            tmpChildView.setOnClickListener(listener);
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置容器中指定标识的单击事件
     *
     * @param container
     * @param resIds
     * @param listener
     */
    public void setOnChildViewClick(View container, int resIds[], View.OnClickListener listener) {
        if (null == container || null == listener || null == resIds) return;

        for (int resId : resIds) {
            View tmpView = container.findViewById(resId);
            if (null != tmpView) {
                tmpView.setOnClickListener(listener);
            }
        }
    }

    /**
     * 设置RadioGroup组件元素的点击事件
     *
     * @param rgp
     * @param clickListener
     */
    public void setRadioGroupItemClicklistener(RadioGroup rgp, View.OnClickListener clickListener) {
        if (null == rgp || null == clickListener) return;

        List<RadioButton> list = this.getRadioButtonsOfRadioGroup(rgp);
        for (RadioButton rbn : list) {
            rbn.setOnClickListener(clickListener);
        }
    }

    /**
     * 设置RadioGroup组件使用状态
     *
     * @param rgp
     * @param enabled
     */
    public void setRadioGroupDisabled(RadioGroup rgp, boolean enabled) {
        if (null == rgp) return;

        List<RadioButton> list = this.getRadioButtonsOfRadioGroup(rgp);
        for (RadioButton rbn : list) {
            rbn.setEnabled(enabled);
        }
    }

    /**
     * 设置RadioGroup指定元素选中
     *
     * @param rgp
     * @param resId
     */
    public void setRadioGroupCheckedByResid(RadioGroup rgp, int resId) {
        if (null == rgp) return;

        List<RadioButton> list = this.getRadioButtonsOfRadioGroup(rgp);
        for (RadioButton rbn : list) {
            if (rbn.getId() == resId) {
                rgp.check(resId);
//                //不推荐使用下面的(设置RadioButton的默认选中, 使用setChecked(true) 这样会使RadioButton一直处于选中状态. )
//                rbn.setChecked(true);
            }
        }
    }

    /**
     * 设置RadioGroup指定元素选中
     *
     * @param rgp
     * @param index
     */
    public void setRadioGroupCheckedByIndex(RadioGroup rgp, int index) {
        if (null == rgp) return;

        List<RadioButton> list = this.getRadioButtonsOfRadioGroup(rgp);
        for (int i = 0; i < list.size(); i++) {
            if (i == index) {
                rgp.check(list.get(i).getId());
                //不推荐使用下面的(设置RadioButton的默认选中, 使用setChecked(true) 这样会使RadioButton一直处于选中状态. )
//                rbn.setChecked(true);
            }
        }
    }

    /**
     * 设置RadioGroup为非选中状态
     *
     * @param rgp
     */
    public void setRadioGroupClearChecked(RadioGroup rgp) {
        if (null == rgp) return;

        rgp.clearCheck();
    }

    /**
     * 读取RadioGroup中的所有RadioButton组件
     *
     * @param rgp
     * @return
     */
    public List<RadioButton> getRadioButtonsOfRadioGroup(RadioGroup rgp) {
        if (null == rgp) return null;

        List<RadioButton> tmpList = new ArrayList<>();
        for (int i = 0; i < rgp.getChildCount(); i++) {
            View childView = rgp.getChildAt(i);
            if (childView instanceof RadioButton) {
                tmpList.add((RadioButton) childView);
            } else if (childView instanceof LinearLayout) {
                LinearLayout tmpLlt = (LinearLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpLlt));
            } else if (childView instanceof GridLayout) {
                GridLayout tmpGlt = (GridLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpGlt));
            }
        }
        return tmpList;
    }

    /**
     * 设置RadioGroup嵌套布局中RadioButton单选
     *
     * @param rgp
     */
    public void setRadioGroupSingleChoice(RadioGroup rgp, IRadioGroupSingleChoice iRadioGroupSingleChoice) {
        if (null == rgp) return;

        List<RadioButton> list = this.getRadioButtonsOfRadioGroup(rgp);
        if (null == list) return;

        //单选限制
        for (RadioButton item : list) {
            item.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        for (RadioButton rbn : list) {
                            if (item.getId() != rbn.getId())
                                rbn.setChecked(false);
                        }
                        iRadioGroupSingleChoice.onCheckedChanged(item);
                    }
                }
            });
        }
    }

    //设置RadioGroup嵌套布局中RadioButton单选（回调事件）
    public interface IRadioGroupSingleChoice {
        void onCheckedChanged(RadioButton radioButton);
    }

    /**
     * 设置RadioGroup组中RadioButton的Tag值为索引；
     *
     * @param rgp
     */
    public void setRadioGroupValue(RadioGroup rgp) {
        if (null == rgp) return;

        List<RadioButton> tmpList = new ArrayList<>();
        for (int i = 0; i < rgp.getChildCount(); i++) {
            View childView = rgp.getChildAt(i);
            if (childView instanceof RadioButton) {
                tmpList.add((RadioButton) childView);
            } else if (childView instanceof LinearLayout) {
                LinearLayout tmpLlt = (LinearLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpLlt));
            } else if (childView instanceof GridLayout) {
                GridLayout tmpGlt = (GridLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpGlt));
            }
        }
        //按照顺序初始化RadioButton的Tag值。
        for (int n = 0; n < tmpList.size(); n++) {
            tmpList.get(n).setTag(n);
        }
    }

    /**
     * 读取RadioGroup中RadioButton选中项的Tag值；
     *
     * @param rgp
     * @return
     */
    public <T> T getRadioGroupValue(RadioGroup rgp) {
        RadioButton tmpRbn = this.getSelfRadioButton(rgp);
        if (null != tmpRbn) {
            return (T) tmpRbn.getTag();
        }
        return null;
    }

    /**
     * 读取RadioGroup中RadioButton选中项的Text值；
     *
     * @param rgp
     * @return
     */
    public String getRadioGroupText(RadioGroup rgp) {
        RadioButton tmpRbn = this.getSelfRadioButton(rgp);
        if (null != tmpRbn) {
            return tmpRbn.getText().toString().trim();
        }
        return null;
    }

    /**
     * 读取RadioGroup选中的RadioButton
     *
     * @param rgp
     * @return
     */
    public RadioButton getRadioGroupCheckedButton(RadioGroup rgp) {
        return this.getSelfRadioButton(rgp);
    }

    /**
     * 读取RadioGroup指定索引的RadioButton
     *
     * @param rgp
     * @param index
     * @return
     */
    public RadioButton getRadioGroupIndexButton(RadioGroup rgp, int index) {
        List<RadioButton> list = this.getSelfRadioButtonList(rgp);
        if (list.size() <= index) return null;
        return list.get(index);
    }

    /**
     * 读取组件值
     *
     * @param view
     * @return
     */
    public String getViewValue(View view) {
        if (null == view) return "";

        if (view instanceof TextView) {
            return ((TextView) view).getText().toString().trim();
        } else if (view instanceof EditText) {
            return ((EditText) view).getText().toString().trim();
        } else if (view instanceof CheckBox) {
            return ((CheckBox) view).getText().toString().trim();
        } else if (view instanceof RadioButton) {
            return ((RadioButton) view).getText().toString().trim();
        } else if (view instanceof Spinner) {
            return ((Spinner) view).getSelectedItem().toString().trim();
        }

        return "";
    }

    /**
     * 读取组件Hint值
     *
     * @param view
     * @return
     */
    public String getViewHint(View view) {
        if (null == view) return "";

        if (view instanceof TextView) {
            return ((TextView) view).getHint().toString().trim();
        } else if (view instanceof EditText) {
            return ((EditText) view).getHint().toString().trim();
        } else if (view instanceof CheckBox) {
            return ((CheckBox) view).getHint().toString().trim();
        } else if (view instanceof RadioButton) {
            return ((RadioButton) view).getHint().toString().trim();
        } else if (view instanceof Button) {
            return ((Button) view).getHint().toString().trim();
        }

        return "";
    }


    /**
     * 读取组件Tag值
     *
     * @param view
     * @return
     */
    public <T> T getViewTag(View view) {
        if (null == view) return null;

        return (T) view.getTag();
    }

    //创建 LinearLayout
    public LinearLayout createLinearLayout(Context context, ViewGroup.LayoutParams layoutParams, int
            orientation, int gravity) {
        LinearLayout llt = new LinearLayout(context);
        llt.setLayoutParams(layoutParams);
        llt.setOrientation(orientation);
        llt.setGravity(gravity);
        return llt;
    }

    //创建 TextView
    public TextView createTextView(Context context, ViewGroup.LayoutParams layoutParams,
                                   String text, int fontSize, int gravity, Drawable background,
                                   int[] padding) {
        TextView textView = new TextView(context);
        if (null != layoutParams) {
            textView.setLayoutParams(layoutParams);
        } else {
            textView.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
        textView.setText(text);
        textView.setTextSize(fontSize);
        if (null != background) {
            textView.setBackground(background);
        }
        textView.setTypeface(null, Typeface.NORMAL);
        if (null != padding) {
            textView.setPadding(padding[0], padding[1], padding[2], padding[3]);
        }
        textView.setGravity(gravity);
        return textView;
    }

    //删除线
    public void setStrikeLine(TextView textView, boolean isUnderline) {
        if (isUnderline) {
            textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
        } else {
            textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
        }
    }

    //首行缩进
    public void setTextViewIndent(Context context, TextView textView, int indentDp, String text) {
        SpannableString ssStr = new SpannableString(text);
        int marginSpanSize = CaValuesHelper.init().dpToPx(context, indentDp);
        LeadingMarginSpan leadingMarginSpan = new LeadingMarginSpan.Standard(marginSpanSize, 0);//仅首行缩进
        ssStr.setSpan(leadingMarginSpan, 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        textView.setText(ssStr);
    }

    //输入框文本显示
    public void setEditTextTextVisiable(EditText ett, boolean isVisiable) {
        if (isVisiable) {
            ett.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
        } else {
            ett.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        }
    }

    /**
     * 根据屏幕尺寸设置View宽与高
     *
     * @param activity
     * @param view
     * @param widthPercent  View宽占屏幕宽的比例
     * @param heightPercent View高占屏幕高的比例
     */
    public void setScreenView(Activity activity, final View view, double widthPercent, double
            heightPercent) {

        DisplayMetrics dm = activity.getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;
        int screenHeight = dm.heightPixels;

        int viewWidth = (int) (screenWidth * widthPercent);
        int viewHeight = (int) (screenHeight * heightPercent);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                viewWidth, viewHeight);
        view.setLayoutParams(params);
    }

    /**
     * 根据屏幕宽度设置View宽与高
     *
     * @param activity
     * @param view
     * @param widthPercent   View宽占屏幕的比例
     * @param viewProportion View宽与高的比例
     */
    public void setViewByScreenWidth(Activity activity, View view, double widthPercent,
                                     double viewProportion) {
        DisplayMetrics dm = activity.getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;

        int viewWidth = (int) (screenWidth * widthPercent);
        int viewHeight = (int) (viewWidth * viewProportion);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                viewWidth, viewHeight);
        view.setLayoutParams(params);
    }

    /**
     * 根据屏幕宽度设置View高
     *
     * @param activity
     * @param view
     * @param widthPercent View宽占屏幕的比例
     */
    public void setViewHeightByScreenWidth(Activity activity, View view, double widthPercent) {
        DisplayMetrics dm = activity.getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;

        int viewHeight = (int) (screenWidth * widthPercent);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                screenWidth, viewHeight);
        view.setLayoutParams(params);
    }

    /**
     * 根据屏幕宽度设置View高
     *
     * @param activity
     * @param view
     * @param widthPercent View宽占屏幕的比例
     * @param viewPadding  View的填充尺寸
     */
    public void setViewHeightByScreenWidth(Activity activity, final View view, double
            widthPercent, int viewPadding) {
        DisplayMetrics dm = activity.getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;
        int height = (int) ((screenWidth - viewPadding) * widthPercent);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                screenWidth, height);
        view.setLayoutParams(params);
    }

    /**
     * 设置文本字体颜色
     *
     * @param originalStr
     * @param keys
     * @param color
     * @return
     */
    public SpannableString setKeyFontColor(String originalStr, String[] keys, String color) {
        for (String key : keys) {
            CaLogHelper.info(TAG, String.format("[setKeyFontColor]原始文本：%s,目标文本：%s,字体颜色：%s", originalStr,
                    key, color));
        }
        SpannableString spannableString = new SpannableString(originalStr);
        if (TextUtils.isEmpty(originalStr)) {
            return spannableString;
        }
        for (String key : keys) {
            int start = originalStr.indexOf(key);
            int end = start + key.length();
            CaLogHelper.info(TAG, String.format("[setKeyFontColor]起始下标：%d,结束下标：%d", start, end));
            spannableString.setSpan(new ForegroundColorSpan(Color.parseColor(color)), start, end,
                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        }
        return spannableString;
    }

    /**
     * 设置字体大小
     *
     * @param originalStr
     * @param key
     * @param dpSize
     * @param isBold
     * @return
     */
    public SpannableString setKeyFontSize(String originalStr, String key, int dpSize,
                                          boolean isBold) {
        CaLogHelper.info(TAG, String.format("[setKeyFontColor]原始文本：%s,目标文本：%s,字体大小：%d", originalStr,
                key, dpSize));

        SpannableString spannableString = new SpannableString(originalStr);
        if (TextUtils.isEmpty(originalStr)) {
            return spannableString;
        }
        int start = originalStr.indexOf(key);
        int end = start + key.length();
        CaLogHelper.info("[setKeyFontColor]", String.format("起始下标：%d,结束下标：%d", start, end));
        spannableString.setSpan(new AbsoluteSizeSpan(dpSize, true), start, end, Spanned
                .SPAN_INCLUSIVE_INCLUSIVE);
        if (isBold) {
            spannableString.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, end,
                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        }
        return spannableString;
    }

    private static CaViewHelper init;

    public static CaViewHelper init() {
        if (null == init) {
            init = new CaViewHelper();
        }
        return init;
    }

    //++++++++++++++++++++++++++++++++++++++
    //++ 内部方法
    //++++++++++++++++++++++++++++++++++++++


    private RadioButton getSelfRadioButton(ViewGroup vgp) {
        RadioButton tmpRbn = null;
        for (int m = 0; m < vgp.getChildCount(); m++) {
            View childView = vgp.getChildAt(m);
            if (childView instanceof RadioButton) {
                RadioButton rbn = ((RadioButton) childView);
                if (rbn.isChecked()) {
                    tmpRbn = rbn;
                    break;
                }
            } else if (childView instanceof LinearLayout) {
                LinearLayout tmpLlt = (LinearLayout) childView;
                RadioButton rbn = this.getSelfRadioButton(tmpLlt);
                if (rbn.isChecked()) {
                    tmpRbn = rbn;
                    break;
                }
            } else if (childView instanceof GridLayout) {
                GridLayout tmpGlt = (GridLayout) childView;
                RadioButton rbn = this.getSelfRadioButton(tmpGlt);
                if (rbn.isChecked()) {
                    tmpRbn = rbn;
                    break;
                }
            }
        }
        return tmpRbn;
    }

    private List<RadioButton> getSelfRadioButtonList(ViewGroup vgp) {
        List<RadioButton> tmpList = new ArrayList<>();
        for (int m = 0; m < vgp.getChildCount(); m++) {
            View childView = vgp.getChildAt(m);
            if (childView instanceof RadioButton) {
                tmpList.add((RadioButton) childView);
            } else if (childView instanceof LinearLayout) {
                LinearLayout tmpLlt = (LinearLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpLlt));
            } else if (childView instanceof GridLayout) {
                GridLayout tmpGlt = (GridLayout) childView;
                tmpList.addAll(this.getSelfRadioButtonList(tmpGlt));
            }
        }
        return tmpList;
    }

    private CaViewHelper() {
        // Private constructor to prevent unwanted construction.
    }
}
